from machine import I2C, Pin
from lib.sensors.ssd1306.protocol import abrobot, i2c
from lib.sensors.ssd1306.render import font_renderer, image_renderer, shape_renderer
from lib.config.index import sensor_config
from utils import device,platform

device.running_ticks_us("lib.sensors.oled.1")


class OLED:
    def __init__(self, scl, sda, width=128, height=64,  freq=400000):
        self.shape_renderer = None
        self.image_renderer = None
        self.font_renderer = None
        self.__scl = scl
        self.__sda = sda
        self.__width = width
        self.__height = height
        self.__i2c = None
        self.__oled = None
        self.__freq = freq
        device.running_ticks_us("lib.sensors.oled.2")
        self.init_i2c()
        self.init_renderer()
        device.running_ticks_us("lib.sensors.oled.3")

    def init_i2c(self):
        """
        初始化i2c接口
        """
        if sensor_config.is_debug():
            print(
                "ssd1306 i2c init:",
                f"scl: {self.__scl},",
                f"sda: {self.__sda},",
                f"width: {self.__width},",
                f"height: {self.__height},",
            )

        if self.__i2c or self.__oled:
            return

        if platform.is_raspberry_pico_series():
            from machine import SoftI2C
            self.__i2c = SoftI2C(scl=Pin(self.__scl), sda=Pin(self.__sda), freq=self.__freq)
        else:
            self.__i2c = I2C(0, scl=Pin(self.__scl), sda=Pin(self.__sda), freq=self.__freq)

        if self.__width == 72:
            # 采用映射方式实现，宽高固定
            if sensor_config.is_debug():
                print(
                    f"ssd1306: load ABrobot 0.42 oled({self.__width}, {self.__height})"
                )
            self.__oled = abrobot.SSD1306_I2C(128, 64, self.__i2c)
        else:
            self.__oled = i2c.SSD1306(self.__width, self.__height, self.__i2c)
        return self.__oled

    def init_renderer(self):
        """不同渲染器"""
        self.font_renderer = font_renderer.FontRenderer(self.__oled)
        self.image_renderer = image_renderer.ImageRender(self.__oled)
        self.shape_renderer = shape_renderer.ShapeImageRender(self.__oled)

    def show(self):
        """显示屏幕"""
        self.__oled.show()

    def clear(self):
        """清除屏幕"""
        self.__oled.clear()

    def clear_rect(self, x, y, w, h):
        """清除矩形区域"""
        self.__oled.rect(x, y, w, h, 0, True)

    def pixel(self, x, y, c = 1):
        """画点"""
        self.__oled.pixel(x, y, c)

    def fill(self, col):
        """填充颜色"""
        self.__oled.fill(col)

    def rect(self, x, y, w, h, col=1, fill=True):
        """绘制矩形"""
        self.__oled.rect(x, y, w, h, col, fill)

    def h_line(self, x, y, w, col=1):
        """绘制水平线"""
        self.__oled.hline(x, y, w, col)

    def line(self, x1, y1, x2, y2, col=1):
        """绘制直线"""
        self.__oled.line(x1, y1, x2, y2, col)

    def power_off(self):
        """关闭电源"""
        self.__oled.poweroff()

    def power_on(self):
        """打开电源"""
        self.__oled.poweron()

    def contrast(self, contrast):
        """设置对比度"""
        self.__oled.contrast(contrast)

    def invert(self, invert):
        """反转"""
        self.__oled.contrast(invert)

    def scroll(self, dx, dy):
        """滚动"""
        self.__oled.scroll(dx, dy)

    def blit(self, buf, x, y):
        """绘制图像"""
        self.__oled.blit(buf, x, y)

    def text(self, string, x_axis, y_axis):
        """显示字符串.
        只支持ascii可见字符
        """
        self.__oled.text(string, x_axis, y_axis)
